package com.sp.reflection.question;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * 反射问题的引入
 */
public class ReflectionQuestion {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        //需求: 根据配置文件 re.properties 指定信息, 创建Cat对象并调用方法hi

        //1. 传统的方式: new 对象 -> 调用其方法
        //1.1 使用Properties类, 来读写配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("chapter23_reflection\\src\\main\\java\\re.properties"));
        String classfullfath = properties.get("classfullpath").toString();
        String methodName = properties.get("method").toString();
        System.out.println("classfullpath = " + classfullfath);
        System.out.println("methodName = " + methodName);
        //1.2 创建对象, 传统的方法, 不能行
        //希望得到properties里面的 classfullpath 的值, 然后创建对象
//        new com.sp.Cat();//
//        new classfullpath();//这里的 classfullpath 是String




        //2. 使用反射机制解决
        //2.1 使用反射机制解决
        Class cls = Class.forName(classfullfath);
        //2.2 通过cls得到加载的类 com.sp.Cat() 的对象实例
        Object o = cls.newInstance();
        System.out.println("o的运行类型 = " + o.getClass());
        //2.3 通过 cls 得到你加载的类 com.sp.Cat() 的methodName"hi" 的方法对象
        Method method1 = cls.getMethod(methodName);
        //2.4 通过method1 调用方法: 即通过方法对象来实现调用方法
        /*
        传统的方法: 对象.方法() 的方式来调用对象的方法
        反射机制: 方法.invoke(对象) 的方式来调用对象的方法
        反射的这种调用方式的作用: 通过外部文件配置, 在不修改源码的情况下来控制程序, 也符合设计模式的ocp原则(开闭原则: 不修改源码, 扩容功能)
         */
        method1.invoke(o);


    }
}
